﻿using System.Text;
using System.Collections.Generic;
using FarseerGames.FarseerPhysics;
using FarseerGames.FarseerPhysics.Collisions;
using FarseerGames.FarseerPhysics.Dynamics.Springs;
using FarseerGames.FarseerPhysics.Factories;
using PhysicsObjects;
using UnitLibrary.DrawingSystem;
using PrototypeGame.ScreenSystem;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
using UnitLibrary.Managers;
using UnitLibrary.GameObjects.Physics; using UnitLibrary.GameObjects.Units;
using UnitLibrary.Utility;
using System;

namespace PrototypeGame.GameScreens
{
    public class MainGameScreen : GameScreen
    {

        protected ComponentM _gameComponents;
               
        private int _gameScreenWidth;
        private  int _gameScreenHeight;

        public  int GameScreenWidth
        {
            get { return _gameScreenWidth; }
        }

        public  int GameScreenHeight
        {
            get { return _gameScreenHeight; }
        }

        protected Game _game;

        protected static int _pointsFTW = 30;

        protected int _gameLevel;

        protected Texture2D _loadingBackground;
        private bool RunGame;
        private Texture2D _textureHealthBar;
        private Texture2D _textureManaBar;
        private Texture2D _textureWaterSentry;
        private Texture2D[] _sentryTextures;
        int numsentries = 3;
        int currentsentry;

        public MainGameScreen(Game game) : base (game)
        {
            _game = game;
            _gameScreenHeight = game.GraphicsDevice.Viewport.Height;
            _gameScreenWidth = game.GraphicsDevice.Viewport.Width;
            currentsentry = 0;
            
        }

        public override void Initialize()
        {
            _gameComponents = new ComponentM(_game, _physicsSimulator, ScreenManager.SpriteBatch);
            base.Initialize();
        }

        public override void LoadContent()
        {
            _gameComponents.LoadContent();
            _gameComponents.playerDied += this.PlayerDied;
            _textureHealthBar = ScreenManager.ContentManager.Load<Texture2D>("content\\images\\healthbar");
            _textureManaBar = ScreenManager.ContentManager.Load<Texture2D>("content\\images\\manabar");
            List<string> names = new List<string> { "watersentry", "firesentry", "earthsentry", "airsentry", "aethersentry", "abilitysentry", "plantsentry" };
            numsentries = names.Count;
            _sentryTextures = new Texture2D[numsentries];
            int i = 0;
            foreach (string name in names)
            {
                _sentryTextures[i] = ScreenManager.ContentManager.Load<Texture2D>("content\\images\\" + name);
                i++;
            }
            
            base.LoadContent();
        }       
        
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {            
            //if(ScreenManager.RunGame)
            //_gameComponents.Update(gameTime);
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
        }
       
        private void PlayerDied()
        {
            EndGame(GameState.PlayerDied);
        }
        /// <summary>
        /// Function to draw the game gui
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Draw(GameTime gameTime)
        {
            if (ScreenManager.RunGame)
            {
                _gameComponents.Draw(ScreenManager.SpriteBatch);
                ScreenManager.SpriteBatch.Begin(SpriteBlendMode.AlphaBlend);
                DrawInGameUI(ScreenManager.SpriteBatch);
                ScreenManager.SpriteBatch.End();
            }
            base.Draw(gameTime);
        }

        private void DrawInGameUI(SpriteBatch spriteBatch)
        {
            Vector2 sentrysize;
            sentrysize.X = 100;
            sentrysize.Y = 100;
            
            float width = ScreenManager.ScreenWidth;
            float height = ScreenManager.ScreenHeight;

            float healthbarpercent = .11f;            
            float healthbarwidth = width * healthbarpercent;

            float manabarpercent = .11f;            
            float manabarwidth = width * manabarpercent;

            float widthspacingpercent = width / (spriteBatch.GraphicsDevice.Viewport.AspectRatio * 32000f); 
            float widthspacing = width * widthspacingpercent;

            float heightspacingpercent = height / 32000;
            float heightspacing = height * heightspacingpercent;

            float currentX = widthspacing;
            float currentY = heightspacing;

            float healthbarscale = healthbarwidth / _textureHealthBar.Width;
            float manabarscale = manabarwidth / _textureManaBar.Width; 

            float totalpercent = 0f;
            totalpercent += healthbarpercent;
            totalpercent += manabarpercent;
            totalpercent += widthspacingpercent * 4;

            
            totalpercent += numsentries * widthspacingpercent;
            float sentrypercent = 1f - totalpercent;
            sentrypercent = sentrypercent / numsentries;
            float sentrywidth = width * sentrypercent;
            float selectedsentrywidth = width * sentrypercent * 1.333f;
            float sentryscale = sentrywidth / sentrysize.X;
            float selectedsentryscale = selectedsentrywidth / sentrysize.X;           

            Vector2 position = new Vector2(widthspacing, 0);
            //Draw the health bar to scale
            position.Y = height - _textureHealthBar.Height * healthbarscale - heightspacing;
            spriteBatch.Draw(_textureHealthBar, position, null, Color.White, 0f, Vector2.Zero, healthbarscale, SpriteEffects.None, 0f);
            position.X += healthbarwidth;
            position.Y = height - sentrysize.Y * selectedsentryscale - heightspacing;
            
            for (int i = 0; i < numsentries; i++)
            {                
                //Add some space
                position.X += widthspacing;
                //if it's not the middle sentry
                if (i != currentsentry)
                {
                    //Draw
                    spriteBatch.Draw(_sentryTextures[i], position, null, Color.White, 0f, Vector2.Zero, sentryscale, SpriteEffects.None, 0f);
                    //Add spacing
                    position.X += sentrywidth;
                }
                else
                {
                    //Draw
                    spriteBatch.Draw(_sentryTextures[i], position, null, Color.White, 0f, Vector2.Zero, selectedsentryscale, SpriteEffects.None, 0f);
                    //Add spacing
                    position.X += selectedsentrywidth;
                }          
            }

            //Draw the mana bar
            position.X += widthspacing;
            position.Y = height -_textureManaBar.Height * manabarscale - heightspacing;
            spriteBatch.Draw(_textureManaBar, position, null, Color.White, 0f, Vector2.Zero, manabarscale, SpriteEffects.None, 0f);

            //Draw health amount
            spriteBatch.DrawString(ScreenManager.SpriteFonts.DetailsFont, "Health: " + _gameComponents.playerManager.Player.Health.ToString(), new Vector2(widthspacing, ScreenManager.ScreenHeight - _textureHealthBar.Height - heightspacing - heightspacing), Color.White);
           
            //Draw the mana bar and mana amount
            spriteBatch.DrawString(ScreenManager.SpriteFonts.DetailsFont, "Mana: " + _gameComponents.playerManager.Player.Points.ToString(), new Vector2(ScreenManager.ScreenWidth - _textureManaBar.Width - widthspacing, ScreenManager.ScreenHeight - _textureManaBar.Height - heightspacing - heightspacing), Color.White);
          
            //Draw the amount of enemy kills
            spriteBatch.DrawString(ScreenManager.SpriteFonts.DetailsFont, "Enemy kills: " + _gameComponents.enemyManager.EnemiesKilled.ToString(), new Vector2(610, 10), Color.White);
        }

        private int righttimer;
        private int lefttimer;
        private void UpdateInGameUI(InputState input)
        {
            //Move forward
            if (input.CurrentKeyboardState.IsKeyDown(Keys.E) && input.LastKeyboardState.IsKeyUp(Keys.E))
            {
                currentsentry++;
                int i = currentsentry + 1;
                if (i > numsentries)
                    currentsentry = 0;
                righttimer = 0;
            }
            else if (input.CurrentKeyboardState.IsKeyDown(Keys.E))
            {
                righttimer++;
                if (righttimer > 15)
                {
                    currentsentry++;
                    int i = currentsentry + 1;
                    if (i > numsentries)
                        currentsentry = 0;
                    righttimer = 0;
                }
            }
            else
                righttimer = 0;

            //Move backwards
            if (input.CurrentKeyboardState.IsKeyDown(Keys.Q) && input.LastKeyboardState.IsKeyUp(Keys.Q))
            {
                currentsentry--;
                int i = numsentries - 1;
                if (currentsentry < 0)
                    currentsentry = i;
                lefttimer = 0;
            }
            else if (input.CurrentKeyboardState.IsKeyDown(Keys.Q))
            {
                lefttimer++;
                if (lefttimer > 15)
                {
                    currentsentry--;
                    int i = numsentries - 1;
                    if (currentsentry < 0)
                        currentsentry = i;
                    lefttimer = 0;
                }
            }
            else
                lefttimer = 0;
        }

        /// <summary>
        /// End the current game
        /// </summary>
        /// <param name="gameState">defines the game state leading to game over</param>
        protected void EndGame(GameState gameState)
        {
            switch (gameState)
            {
                case GameState.PlayerDied:
                    ScreenManager.AddScreen(new PauseScreen("Game Over", "You Died!", this, true));
                    ExitScreen();
                    break;
                case GameState.PlayerWonByPoints:
                    ScreenManager.AddScreen(new PauseScreen("You Won", "You were victorious over the evil forces!", this, true));
                    ExitScreen();
                    break;
                default:
                    break;
            }
            ScreenManager.RunGame = false;
        }

        /// <summary>
        /// Handle input as this is a game screen
        /// </summary>
        /// <param name="input"></param>
        public override void HandleInput(InputState input)
        {
            if (FirstRun)
            {
                ScreenManager.AddScreen(new PauseScreen(GetTitle(), GetDetails(), this));
                FirstRun = false;
            }

            if (input.PauseGame)
            {
                ScreenManager.AddScreen(new PauseScreen(GetTitle(), GetDetails(), this));
            }

            if (input.CurrentGamePadState.IsConnected)
            {
                HandleGamePadInput(input);
            }
            else
            {
                HandleKeyboardInput(input);
#if !XBOX
                HandleMouseInput(input);
#endif
            }

            base.HandleInput(input);
        }




        public override void UnloadContent()
        {
            //Called by screen manager when the game screen is to be deleted
            //Will automatically delete component manager
            base.UnloadContent();
        }

        private void HandleGamePadInput(InputState input)
        {
            
        }

        /// <summary>
        /// TODO: change all keyboard input to this
        /// </summary>
        /// <param name="input"></param>
        private void HandleKeyboardInput(InputState input)
        {
            UpdateInGameUI(input);
        }

#if !XBOX
        private void HandleMouseInput(InputState input)
        {
            
        }
#endif

        public static string GetTitle()
        {
            return "Saeculum Game";
        }

        public static string GetDetails()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("This is a Dynamic Tower Defense Game");
            sb.AppendLine(string.Empty);
            sb.AppendLine("Controls:");
            sb.AppendLine(string.Empty);
            sb.AppendLine("Mouse: ");
            sb.AppendLine("    -Left click: Fire Bullet");
            sb.AppendLine("    -Right click: Summon Tower");
            sb.AppendLine(string.Empty);
            sb.AppendLine("Keyboard: ");
            sb.AppendLine("    -Movement: WASD");
            sb.AppendLine(string.Empty);
            sb.AppendLine("Game objectives are based on which level you selected. ");
            return sb.ToString();
        }
    }
}